﻿using CommunityToolkit.Mvvm.ComponentModel;
using Daq.Devices;
using Daq.Utils;
using Daq.ViewModels;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows.Media.Animation;

namespace Daq.Services
{
    public class SystemSettings : ObservableValidator
    {
        [JsonPropertyName("device")]
        public DeviceInfo Device { get; set; } = new();
        private string dataDirectory = @"C:\ProgramData\数采系统\data";
        [JsonPropertyName("dataDirectory")]
        public string DataDirectory 
        {
            get => dataDirectory;
            set
            {
                SetProperty(ref dataDirectory, value);
            }
        }

        private string prefix = "";
        [JsonPropertyName("prefix")]
        [CustomValidation(typeof(SystemSettings), nameof(ValidateFileName))]
        public string Prefix 
        {
            get => prefix;
            set
            {
                SetProperty(ref prefix, value, true);
            }
        }

        public static ValidationResult? ValidateFileName(string fileName, ValidationContext context)
        {
            if (string.IsNullOrEmpty(fileName))
            {
                return ValidationResult.Success;
            }

            try
            {
                // 检查是否包含无效字符
                char[] invalidChars = Path.GetInvalidFileNameChars();
                foreach (char c in fileName)
                {
                    if (Array.IndexOf(invalidChars, c) != -1)
                    {
                        return new ValidationResult($"文件名包含无效字符: {c}");
                    }
                }

                // 检查是否为特殊名称
                string[] specialNames = { ".", ".." };
                if (Array.IndexOf(specialNames, fileName.Trim()) != -1)
                {
                    return new ValidationResult("文件名不能为 '.' 或 '..'");
                }

                // 检查是否以空格或点结尾
                if (fileName.TrimEnd().Length != fileName.Length || fileName.TrimEnd('.').Length != fileName.Length)
                {
                    return new ValidationResult("文件名不能以空格或点结尾");
                }

                return ValidationResult.Success;
            }
            catch (Exception)
            {
                return new ValidationResult("文件名验证出错");
            }
        }
    }

    public class DaqsSettings
    {
        [JsonPropertyName("daqs")]
        public List<DaqInfo>? Daqs { get; set; }
    }


    public class SettingsService
    {
        public Settings<UserSettings> UserSettings { get; set; } = new ("user.cfg");
        public Settings<DaqsSettings> DaqsSettings { get; set; } = new ("daqsSettings.cfg");
        public Settings<SystemSettings> SystemSettings { get; set; } = new ("sys.cfg");
        public List<DeviceInfo>? Devices { get; set; }
    }

    public class UserSettings 
    {
        [JsonPropertyName("channels")]
        public List<int>? Channels { get; set; }
    }

    public class Settings<T> where T : new()
    {
        public static DirectoryInfo RootDirectory = Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Daq\");
        private string settingsFilePath;
        public T Instance { get; set; } = new T();
        private readonly ILogger? logger;
        public Settings(string fileName)
        {
            logger = App.Current.Services.GetService<ILogger>();
            if(string.IsNullOrWhiteSpace(fileName))
            {
                throw new Exception("文件名称不能为空");
            }
            settingsFilePath = RootDirectory.FullName + fileName;
            AsyncHelper.RunSync(Load);
        }

        public async Task Load()
        {
            logger?.Information($"载入配置文件{settingsFilePath}");
            var instanceBackup = Instance;
            if (settingsFilePath == null || string.IsNullOrWhiteSpace(settingsFilePath))
            {
                logger?.Error("配置文件路径为空");
                return;
            }
            if (!File.Exists(settingsFilePath))
            {
                logger?.Information($"配置文件({settingsFilePath})不存在,新建该文件");
                Instance = new T();
                await Save();
                return;
            }
            try
            {
                string text = await File.ReadAllTextAsync(settingsFilePath);
                Instance = JsonSerializer.Deserialize<T>(text) ?? new T();
            }
            catch(Exception ex)
            {
                logger?.Error($"配置文件打开失败:{ex.Message}");
                throw new Exception("配置文件打开失败");
            }
        }
        public async Task Save()
        {
            logger?.Information($"保存配置文件{settingsFilePath}");
            string str = JsonSerializer.Serialize(Instance);
            await FileHelper.WriteTextAsync(settingsFilePath, str);
            await Load();
        }

        public async Task Export(string destFilePath)
        {
            logger?.Information($"导出配置文件到{destFilePath}");
            await Task.Run(()=> File.Copy(settingsFilePath, destFilePath, true));
        }

        public async Task Import(string sourceFilePath)
        {
            logger?.Information($"从{sourceFilePath}导入配置文件");
            await Task.Run(()=> File.Copy(sourceFilePath, settingsFilePath, true));
            await Load();
        }
    }
}
